home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / cutNpaste / Motif+Xt / docut_motif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  18.5 KB  |  719 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18.  
  19. #include <X11/Xm/Xm.h>
  20. #include <X11/Xm/CutPaste.h>
  21.  
  22. extern char *getSelection();/* function to get the current molecule */
  23. Window mc_win = 0;        /* the single window to use in Motif clipboard calls */
  24.  
  25. char *theSelection=NULL;    /* the selection - mol as text */
  26. char *augSelection=NULL;    /* the augmented selection - mol + rotation */
  27. char *xferSelection;        /* space for the selection when it's pasted */
  28.  
  29. extern short xRot, yRot;    /* x and y rotation values for keeping for c&p */
  30.  
  31. int wantPersistance = 1;    /* whether or not to remember data when app exits */
  32.  
  33. #define EV    1000            /* Escape velocity: don't spin waiting for the
  34.                             lock too long before asking if the user wants
  35.                             to keep waiting */
  36.  
  37. #define MXCHARS 30
  38.  
  39. /*
  40.  * pasteCB()
  41.  *        paste call back
  42.  *    
  43.  *        request the data as a string
  44.  */
  45. void pasteCB(Widget w, caddr_t client_data, XmAnyCallbackStruct *call_data) {
  46.  
  47.     Display *d = XtDisplay(w);
  48.     Window win = XtWindow(w);
  49.     Time time_of_request = XtLastTimestampProcessed(d);
  50.     int count, nbuflen, private;
  51.     unsigned long numcopied, buflen;
  52.     char *namebuf=NULL;
  53.     char *buffer=NULL;
  54.  
  55.     char *cptr=NULL;
  56.     char axRot[MXCHARS], ayRot[MXCHARS], head[MXCHARS];
  57.     int i,j,k,length,ret,found_match;
  58.  
  59. #ifdef EBUG
  60.     win = XtWindow(XtParent(w));
  61.     fprintf(stderr,"in Paste\n");
  62. #endif
  63.         /* The application should call all the
  64.          * Motif clipboard calls with the SAME
  65.          * window id.  It really doesn't matter
  66.          * which one, as long as it is associated
  67.          * with a widget.  In this case, the cut/
  68.          * copy/paste widgets each have a window
  69.          * associated with them.  In the widget
  70.          * hierarchy, they share a parent window.
  71.          * The programmer can either use the parent
  72.          * window, or any of the windows, provided
  73.          * that it is the same for any of the calls
  74.          * to the Motif clipboard.
  75.          */
  76.         if (mc_win == 0)
  77.             mc_win = win;
  78.         else if (mc_win != win) {
  79.             win = mc_win;
  80.         }
  81.  
  82.  
  83.     /*
  84.      * Start the retrieve.  This locks the clipboard so that
  85.      * no other application can get any info from the clipboard.
  86.      * Be sure that this will be followed by an EndRetrieve
  87.      * sometime in the near future.
  88.      *
  89.      * The programmer may want to have some sort of 'escape'
  90.      * count here in each of these calls (if spinning on
  91.      * the availability of the clipboard) - to be sure not
  92.      * to loop infinitely - and to quiz the user if the operation
  93.      * appears to be taking a loooong time.
  94.      * Or just bop on back if want instant gratification...
  95.      */
  96.     if (XmClipboardStartRetrieve(d, win, time_of_request) == ClipboardLocked) {
  97.         fprintf(stderr,"Clipboard is locked - Try again later\n");
  98.         XBell( XtDisplay(w), 0);
  99.         return;
  100.     }
  101.  
  102.     /*
  103.      * Find out how many different formats (targets in 'X' land)
  104.      * there are posted to the Motif clipboard.  This routine
  105.      * also returns the length of the longest format name in
  106.      * nbuflen, so the programmer knows how much space to allocate.
  107.      *
  108.      * This call could return ClipboardLocked had we not called it
  109.      * within the StartRetrieve, EndRetrieve pair.
  110.      */
  111.     if (XmClipboardInquireCount(d, win, &count, &nbuflen) == ClipboardNoData) {
  112.         XmClipboardEndRetrieve(d, win);
  113.         XBell( XtDisplay(w), 0);
  114.         fprintf(stderr,"no data in the clipboard\n");
  115.         return;
  116.     } 
  117. #ifdef EBUG
  118.     fprintf(stderr,"Count is %d\n",count);
  119. #endif
  120.  
  121.  
  122.     /* 
  123.      * Now look at all the formats - 
  124.      * this is useful if your application has a preferred format.
  125.      *
  126.      * Note: Motif starts counting its formats at 1.
  127.      *
  128.      * Be careful when getting data back from the clipboard
  129.      * that you will interpret as a string.  Not everyone is
  130.      * careful about counting the '\0' as a character.
  131.      *
  132.      * This call could return ClipboardLocked had we not called it
  133.      * within the StartRetrieve, EndRetrieve pair.
  134.      * This call could return ClipboardNoData but we already know
  135.      * that there's data from the above call - and we have the clipboard
  136.      * locked.
  137.      * This call could return ClipboardTruncate if the buffer we passed
  138.      * it was not large enough for the format name - but we checked
  139.      * its size above.
  140.      */
  141.     found_match = 0;
  142.     namebuf = (char *)malloc(sizeof(char)*(nbuflen+1));
  143.     for (i=1; (i<=count) && (found_match==0); i++) {
  144.         if (XmClipboardInquireFormat(d, win, i, namebuf, nbuflen, &numcopied) ==
  145.             ClipboardNoData) {
  146.             XmClipboardEndRetrieve(d, win);
  147.             XBell( XtDisplay(w), 0);
  148.             free(namebuf);
  149.             fprintf(stderr,"no data in the clipboard\n");
  150.             return;
  151.         } else {
  152.             namebuf[numcopied] = '\0';
  153.             /* this demo only looks for string */
  154.             if (! strcmp(namebuf,"string") || ! strcmp(namebuf,"STRING") 
  155.                 || ! strcmp(namebuf,XmRString) ) {
  156.                 found_match = i;
  157.             }
  158. #ifdef EBUG
  159.             fprintf(stderr,"namebuf is %s\n",namebuf);
  160. #endif
  161.         }
  162.     }
  163.  
  164.  
  165.     /*
  166.      * Now find out how big the data is in this format.
  167.      *
  168.      * This call could return ClipboardLocked had we not called it
  169.      * within the StartRetrieve, EndRetrieve pair.
  170.      * This call could return ClipboardNoData but we already know
  171.      * that there's data from the above call - and we have the clipboard
  172.      * locked.
  173.      */
  174.     XmClipboardInquireLength(d, win, namebuf, &buflen);
  175.     if (buflen == 0) {
  176.         XmClipboardEndRetrieve(d, win);
  177.         XBell( XtDisplay(w), 0);
  178.         fprintf(stderr,"PASTE - 0 length data!!\n");
  179.         free(namebuf);
  180.         return;
  181.     }
  182. #ifdef EBUG
  183.     fprintf(stderr,"buflen is %d\n",buflen);
  184. #endif
  185.  
  186.     /*
  187.      * Get the data.
  188.      *
  189.      * This can be done incrementally if the programmer decides
  190.      * to allocate a smaller buffer size.  Just call XmClipboardRetrieve()
  191.      * multiple times and be sure to add the code that deals with 
  192.      * patching the data back together or processes the data in the loop.
  193.      *
  194.      * This call returns the actual number of bytes copied in the transaction.
  195.      * It also returns any private data that was stored with the data.
  196.      * This is useful for passing secret messages.
  197.      *
  198.      * The clipboard is STILL locked - so no way will we be seeing the
  199.      * ClipboardLocked or ClipboardNoData returns.  And we shouldn't
  200.      * see the ClipboardTruncate cause we've allocated enough space.
  201.      */
  202.     buffer = (char *)malloc(sizeof(char)*(buflen+1));
  203.     while (( (ret = XmClipboardRetrieve(d, win, namebuf, buffer, buflen, &numcopied, &private)) != ClipboardSuccess) ) {
  204. #ifdef EBUG
  205.         fprintf(stderr,"ret is %d\n",ret);
  206. #endif
  207.     }
  208.  
  209.     buffer[buflen] = '\0';
  210.  
  211.  
  212.     /*
  213.      * Just an extra check to be sure that we really got all the data.
  214.      */
  215.     if (numcopied != buflen) {
  216.         fprintf(stderr,"Didn't copy all that it should\n");
  217.         XmClipboardEndRetrieve(d, win);
  218.         XBell( XtDisplay(w), 0);
  219.         free(buffer);
  220.         free(namebuf);
  221.         return;
  222.     }
  223.  
  224.  
  225.     /*
  226.      * Clean up temporary space.  And let go of the clipboard! 
  227.      */
  228.     free(namebuf);
  229.     XmClipboardEndRetrieve(d, win);
  230.  
  231.  
  232.     /*
  233.      * Now that the data is finally here,
  234.      * do something with it in the application.
  235.      * In this case, draw the molecule 
  236.      *
  237.      * This is the demo's format that it
  238.      * can understand (header):
  239.      *  _MOL
  240.      *    xrot  as %d
  241.      *  yrot  as %d
  242.      *
  243.      *  followed by:
  244.      *  molecule format that the graphics portion
  245.      *  of this program knows how to render
  246.      *  basically, allowing comments, molecule
  247.      *  name, color, and positions
  248.      */
  249.  
  250.         /* first play with grabbing the saved rotation values */
  251.         cptr = buffer;
  252.         i=0;
  253.         while ((*(cptr+i) != '\n') && (i<MXCHARS)) {
  254.             head[i++] = *(cptr+i);
  255.         }
  256.         head[i] ='\0';
  257.         i++;
  258.         if ( strcmp(head,"_MOL") ) {
  259.             XBell( XtDisplay(w), 0);
  260.             fprintf(stderr,"Paste not in _MOL format\n");
  261.             free(buffer);
  262.             return;
  263.         }
  264.  
  265.         j = 0;
  266.         while ((*(cptr+i) != '\n') && (j<MXCHARS)) {
  267.             axRot[j++] = *(cptr+i);
  268.             i++;
  269.         }
  270.         axRot[j] = '\0';
  271.         i++;
  272.  
  273.         k = 0;    
  274.         while ((*(cptr+i) != '\n') && (k<MXCHARS)) {
  275.             ayRot[k++] = *(cptr+i);
  276.             i++;
  277.         }
  278.         ayRot[k] = '\0';
  279.         i++;
  280.  
  281.         xRot = (short) atoi(axRot);
  282.         yRot = (short) atoi(ayRot);
  283.                 
  284.             
  285.         length = strlen(buffer+i);
  286.         /* 
  287.          * molecule program will free this data when this 
  288.          * molecule is replaced 
  289.          */
  290.         xferSelection =(char *)malloc(sizeof(char)*(length+1));
  291.         strcpy(xferSelection, (char *) (buffer+i));
  292. #ifdef EBUG
  293.         fprintf(stderr,"xferSelection %s\n",xferSelection);
  294. #endif
  295.         free(buffer);
  296.  
  297.     buildMolecule(xferSelection);
  298.  
  299.     drawScene();
  300.         return ;
  301. }
  302.  
  303.  
  304.  
  305. /*
  306.  * copynameCB()
  307.  *        copy by name call back  (registered from the copyCB() )
  308.  *    
  309.  *        If the data was copied to the Motif clipboard
  310.  *         by name (reference), then now is the time to
  311.  *         really copy the data there, cause someone has
  312.  *         asked for it - through paste - or if the
  313.  *        through quit.  This gets called if
  314.  *        data is deleted from the clipboard as well.
  315.  */
  316. void copynameCB(Widget w, int *data_id, int *private, int *reason) {
  317.  
  318.     Display *d = XtDisplay(w);
  319.     Window win = XtWindow(w);
  320.     int    escape;
  321. #ifdef EBUG
  322. win = XtWindow(XtParent(w));
  323. #endif
  324.  
  325. fprintf(stderr,"In copybynameCB\n");
  326.  
  327.         /* The application should call all the
  328.          * Motif clipboard calls with the SAME
  329.          * window id.  It really doesn't matter
  330.          * which one, as long as it is associated
  331.          * with a widget.  In this case, the cut/
  332.          * copy/paste widgets each have a window
  333.          * associated with them.  In the widget
  334.          * hierarchy, they share a parent window.
  335.          * The programmer can either use the parent
  336.          * window, or any of the windows, provided
  337.          * that it is the same for any of the calls
  338.          * to the Motif clipboard.
  339.          */
  340.         if (mc_win ==0)
  341.             mc_win = win;
  342.         else if (mc_win != win) {
  343.             win = mc_win;
  344.         }
  345.  
  346.     /*
  347.      * There are two reasons this routine is called.
  348.      * Either someone has requested the data through
  349.      * the paste -- or the Motif clipboard has been
  350.      * used by someone else and it's ok to remove
  351.      * the data from the application.
  352.      */
  353.     escape = 0;
  354.     if (*reason == XmCR_CLIPBOARD_DATA_REQUEST) {
  355.         while ((escape++ < EV) && 
  356.                 XmClipboardCopyByName(d, 
  357.                                 win, 
  358.                                 *data_id, 
  359.                                 augSelection, 
  360.                                 (long) strlen(augSelection), 
  361.                                 *private) != ClipboardSuccess) ;    
  362.         if (escape >= EV) {
  363.             /* Clipboard is locked and I can't get it */
  364.             fprintf(stderr,"Clipboard is locked - Try again later\n");
  365.             XBell( XtDisplay(w), 0);
  366.             return;
  367.         }
  368.  
  369.     } else if (*reason == XmCR_CLIPBOARD_DATA_DELETE) {
  370.         /* ok to delete data - 
  371.          * Motif clipboard doesn't need it any longer.
  372.          * So get rid of it if keeping it in a special place.
  373.          */
  374.         fprintf(stderr,"copynameCB Data delete\n");
  375.     }
  376. }
  377.  
  378.  
  379. /*
  380.  * copyCB()
  381.  *        copy call back  
  382.  *
  383.  *    copy the data as a string
  384.  *
  385.  *  demonstrates "copy by name" to the motif clipboard
  386.  *    
  387.  */
  388. void copyCB(Widget w, caddr_t client_data, XmAnyCallbackStruct *call_data) {
  389.     int rv, incr;
  390.     char arot[MXCHARS*3];
  391.     Display *d = XtDisplay(w);
  392.     Window win = XtWindow(w);
  393.     Time time_of_request = XtLastTimestampProcessed(d);
  394.     long item_id; 
  395.     int data_id;
  396.     int private=0;
  397.  
  398. #ifdef EBUG
  399. win = XtWindow(XtParent(w));
  400. #endif
  401.  
  402.     /* do some cleanup of the selection if necessary */
  403.     if (theSelection)
  404.         free(theSelection);
  405.     if (augSelection)
  406.         free(augSelection);
  407.     theSelection = getSelection();
  408.     if (theSelection == NULL) {
  409.         fprintf(stderr,"Nothing selected\n");
  410.         XBell( d, 0);
  411.     } else {
  412.  
  413. #ifdef EBUG
  414.         fprintf(stderr,"theSelection %s\n",theSelection);
  415.         printf("\n%s\n", theSelection);
  416. #endif
  417.  
  418.         /* The application should call all the
  419.          * Motif clipboard calls with the SAME
  420.          * window id.  It really doesn't matter
  421.          * which one, as long as it is associated
  422.          * with a widget.  In this case, the cut/
  423.          * copy/paste widgets each have a window
  424.          * associated with them.  In the widget
  425.          * hierarchy, they share a parent window.
  426.          * The programmer can either use the parent
  427.          * window, or any of the windows, provided
  428.          * that it is the same for any of the calls
  429.          * to the Motif clipboard.
  430.          */
  431.         if (mc_win ==0)
  432.             mc_win = win;
  433.         else if (mc_win != win) {
  434.             win = mc_win;
  435.         }
  436.  
  437.         sprintf(arot,"_MOL\n%d\n%d\n",xRot,yRot);
  438.         incr = strlen(arot);
  439.         augSelection = (char *)malloc(sizeof(char)*(strlen(theSelection)+incr+1));
  440.         sprintf(augSelection,"%s%s",arot,theSelection);
  441.  
  442.         
  443.         /*
  444.          * Start your copy.  This locks the clipboard for you.
  445.          * Here is where you register your callback if you
  446.          * will be using CopyByName.
  447.          *
  448.          */
  449.         while (XmClipboardStartCopy(
  450.                             d, 
  451.                             win, 
  452.                             XmStringCreate("mol.good",XmSTRING_DEFAULT_CHARSET),
  453.                             time_of_request, 
  454.                             w,
  455.                             /*
  456.                             copynameCB, 
  457.                             */
  458.                             NULL, 
  459.                             &item_id) != ClipboardSuccess) ;
  460.  
  461.         /*
  462.          * Copy the data - either by name by passing NULL
  463.          * or by doing the copy of the data (augSelection).
  464.          *
  465.          * Any format passed by name is assumed to have the length
  466.          * passed in a call to XmClipboardCopy, even though the data
  467.          * has not yet been transferred to the clipboard in that
  468.          * format.
  469.          */
  470.         while (XmClipboardCopy(
  471.                             d, 
  472.                             win, 
  473.                             item_id, 
  474.                             /*
  475.                             XmRString, 
  476.                             */
  477.                             "STRING", 
  478.                             augSelection,     /* not by name */
  479.                             (long) strlen(augSelection), 
  480.                             private, 
  481.                             &data_id) != ClipboardSuccess) ;
  482.  
  483.         /*
  484.          * Up until the EndCopy, all of the transfers are going
  485.          * to a temporary buffer.  EndCopy makes the data go
  486.          * all the way to the clipboard.
  487.          */
  488.         while (XmClipboardEndCopy(d, win, item_id) != ClipboardSuccess)  ;
  489.  
  490.     }
  491. }
  492.  
  493.  
  494. /*
  495.  * cutCB()
  496.  *        cut call back  
  497.  *
  498.  *    cut the data as a string and give it to the clipboard
  499.  *
  500.  *  This routine is just like copyCB() except that some
  501.  *  application data structures have to change and the 
  502.  *  display should reflect that change.
  503.  *    
  504.  *
  505.  *  demonstrates "direct copy" to the motif clipboard
  506.  *    
  507.  */
  508. void cutCB(Widget w) {
  509.     int rv, incr;
  510.     char arot[MXCHARS*3];
  511.     Display *d = XtDisplay(w);
  512.     Window win = XtWindow(w);
  513.     Time time_of_request = XtLastTimestampProcessed(d);
  514.     long item_id; 
  515.     int data_id;
  516.     int private=0;
  517.     char *empty=NULL;            /* an empty string */
  518.  
  519. #ifdef EBUG
  520. win = XtWindow(XtParent(w));
  521. #endif
  522.  
  523.     if (theSelection)
  524.         free(theSelection);
  525.     if (augSelection)
  526.         free(augSelection);
  527.     if (empty)
  528.         free(empty);
  529.     theSelection = getSelection();
  530.     if (theSelection == NULL) {
  531.         fprintf(stderr,"Nothing selected\n");
  532.         XBell( d, 0);
  533.     } else {
  534.  
  535. #ifdef EBUG
  536.         fprintf(stderr,"theSelection %s\n",theSelection);
  537.         printf("\n%s\n", theSelection);
  538. #endif
  539.  
  540.         /* The application should call all the
  541.          * Motif clipboard calls with the SAME
  542.          * window id.  It really doesn't matter
  543.          * which one, as long as it is associated
  544.          * with a widget.  In this case, the cut/
  545.          * copy/paste widgets each have a window
  546.          * associated with them.  In the widget
  547.          * hierarchy, they share a parent window.
  548.          * The programmer can either use the parent
  549.          * window, or any of the windows, provided
  550.          * that it is the same for any of the calls
  551.          * to the Motif clipboard.
  552.          */
  553.         if (mc_win ==0)
  554.             mc_win = win;
  555.         else if (mc_win != win) {
  556.             win = mc_win;
  557.         }
  558.  
  559.         /* get the selected data */
  560.         sprintf(arot,"_MOL\n%d\n%d\n",xRot,yRot);
  561.         incr = strlen(arot);
  562.         augSelection = (char *)malloc(sizeof(char)*(strlen(theSelection)+incr+1));
  563.         sprintf(augSelection,"%s%s",arot,theSelection);
  564.  
  565.         /*
  566.          * Start your copy.  This locks the clipboard for you.
  567.          * Here is where you register your callback if you
  568.          * will be using CopyByName.
  569.          *
  570.          */
  571.         while (XmClipboardStartCopy(
  572.                             d, 
  573.                             win, 
  574.                             XmStringCreate("mol.good",XmSTRING_DEFAULT_CHARSET),
  575.                             time_of_request, 
  576.                             w,
  577.                             copynameCB, 
  578.                             &item_id) != ClipboardSuccess) ;
  579.   
  580.         /*
  581.          * Copy the data - either by name by passing NULL
  582.          * or by doing the copy of the data (augSelection).
  583.          *
  584.          * Any format passed by name is assumed to have the length
  585.          * passed in a call to XmClipboardCopy, even though the data
  586.          * has not yet been transferred to the clipboard in that
  587.          * format.
  588.          *
  589.          * Here, we transfer it explicitly, just to show the other
  590.          * method (as opposed to the CopyByName used in the copyCB()).
  591.          *
  592.          */
  593.         while (XmClipboardCopy(
  594.                             d, 
  595.                             win, 
  596.                             item_id, 
  597.                             /*
  598.                             XmRString, 
  599.                             */
  600.                             "STRING", 
  601.                             augSelection, 
  602.                             (long) strlen(augSelection),  
  603.                             private, 
  604.                             &data_id) != ClipboardSuccess) ;
  605.  
  606.         while (XmClipboardEndCopy(d, win, item_id) != ClipboardSuccess)  ;
  607.         /*
  608.          * Up until the EndCopy, all of the transfers are going
  609.          * to a temporary buffer.  EndCopy makes the data go
  610.          * all the way to the clipboard.
  611.          */
  612.  
  613.     /* now draw no molecules */
  614.     empty = (char *)malloc(sizeof(char));
  615.     *empty = '\0';
  616.     buildMolecule(empty);
  617.  
  618.     drawScene();
  619.         return ;
  620.  
  621.     }
  622. }
  623.  
  624.  
  625. /*
  626.  * quitCB()
  627.  *
  628.  *    quit call back...  call on exit
  629.  *
  630.  * Need to clean up here - if I am the clipboard owner of something by
  631.  * name,  I must either remove the format or release the data.
  632.  */
  633. quitCB(Widget w, caddr_t client_data, XmAnyCallbackStruct *call_data) {
  634.  
  635.     Display *d = XtDisplay(w);
  636.     Window win = XtWindow(w);
  637.     XmClipboardPendingList retlist;
  638.     unsigned long count;
  639.     int i, ret;
  640.  
  641.     /*
  642.      * Use the same window id
  643.      */
  644.     if (mc_win ==0)
  645.             mc_win = win;
  646.     else if (mc_win != win) {
  647.             win = mc_win;
  648.     }
  649.  
  650.     /*
  651.      * Check to see if there are any copy by names that have
  652.      * never passed their data to the clipboard.
  653.      */
  654.     while (XmClipboardInquirePendingItems(
  655.                             d, 
  656.                             win, 
  657.                             /*
  658.                             XmRString, 
  659.                             */
  660.                             "STRING", 
  661.                             &retlist,
  662.                             &count) != ClipboardSuccess) ;
  663. #ifdef EBUG
  664.     fprintf(stderr,"count is %d\n",count);
  665.     for (i=0; i<count; i++) {
  666.         fprintf(stderr,"data id %d  | private id %d \n", (retlist+i)->DataId,
  667.             (retlist+i)->PrivateId);
  668.     }
  669. #endif
  670.  
  671.     if (count == 0) {
  672.         /* then no copy by name data pending on the clipboard */
  673.         XtFree(retlist);
  674.         exit(0);
  675.     } else {
  676.  
  677.         /*
  678.          * Don't want the data hanging around.
  679.          * Explicitly get rid of it.
  680.          */
  681.         if ( ! (wantPersistance==1)) {
  682.  
  683.             for (i=0; i<count; i++) {
  684.  
  685.                 /* if do this, then data will not persist beyond app quiting */
  686.                 while (XmClipboardWithdrawFormat(
  687.                             d, 
  688.                             win, 
  689.                             (retlist+i)->DataId) != ClipboardSuccess);
  690.             }
  691.  
  692.         } else {
  693.  
  694.             /*
  695.              * Get the data onto the clipboard
  696.              */
  697.             for (i=0; i<count; i++) {
  698.                 while ((ret=XmClipboardCopyByName(d, win, (retlist+i)->DataId, 
  699.                     augSelection, (long) strlen(augSelection), (retlist+i)->PrivateId)) != ClipboardSuccess) {
  700.                 fprintf(stderr,"ret is %d\n",ret);
  701.                 }
  702.  
  703.             }
  704.         }
  705.  
  706.     }
  707.  
  708.     /* app is responsible for freeing the list memory */
  709.     XtFree(retlist);        
  710.  
  711.     /* be sure that the data makes it to the clipboard
  712.      */
  713.     XSync(d, 0);
  714.     XtCloseDisplay(d);
  715.     exit(0);
  716.  
  717. }
  718.  
  719.